package cn.cyh.queue_service.mq.consumer;

import cn.cyh.queue_service.config.RabbitMQConfig;
import cn.cyh.queue_service.mq.event.CompleteServiceEvent;
import cn.cyh.queue_service.mq.event.NewCallEvent;
import cn.cyh.queue_service.mq.event.VerifyEvent;
import cn.cyh.queue_service.service.CacheService;
import cn.cyh.queue_service.service.StatisticsService;
import cn.cyh.queue_service.websocket.CallMessage;
import cn.cyh.queue_service.websocket.CallScreenWebSocketHandler;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rabbitmq.client.Channel;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.concurrent.TimeUnit;

/**
 * 叫号事件消费者
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class CallEventConsumer {

    private final CallScreenWebSocketHandler webSocketHandler;
    private final StatisticsService statisticsService;
    private final CacheService cacheService;
    private final ObjectMapper objectMapper;
    
    /**
     * 处理新叫号事件
     *
     * @param message 消息
     * @param channel 通道
     */
    @RabbitListener(queues = RabbitMQConfig.QUEUE_CALL_NOTIFICATION)
    public void handleNewCallEvent(Message message, Channel channel) throws IOException {
        try {
            // 获取消息内容
            String content = new String(message.getBody());
            NewCallEvent event = objectMapper.readValue(content, NewCallEvent.class);
            if (!RabbitMQConfig.QUEUE_CALL_NOTIFICATION.equals(event.getEventType())) {
                return;
            }
            log.info("收到叫号事件: {} -> 窗口{}", event.getTicketNumber(), event.getWindowNumber());
            
            // 构造叫号屏消息
            CallMessage callMessage = CallMessage.builder()
                    .queueNumber(event.getTicketNumber())
                    .windowNumber(event.getWindowNumber())
                    .windowName(event.getWindowName())
                    .businessTypeId(event.getServiceTypeId())
                    .businessTypeName(event.getBusinessType())
                    .areaId(event.getAreaId())
                    .areaName(event.getAreaName())
                    .callTime(LocalDateTime.now())
                    .audioUrl(event.getAudioUrl())
                    .build();
            
            // 通过WebSocket发送叫号消息
            webSocketHandler.broadcastCallMessage(callMessage);
            
            // 更新统计数据
            statisticsService.updateCallStats(event.getServiceTypeId(), event.getWindowId());
            
            // 确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            log.error("处理叫号事件失败", e);
            
            // 拒绝消息并重新入队
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
        }
    }
    
    /**
     * 处理验证事件
     *
     * @param message 消息
     * @param channel 通道
     */
    @RabbitListener(queues = RabbitMQConfig.QUEUE_STATUS_CHANGE)
    public void handleVerifyEvent(Message message, Channel channel) throws IOException {
        try {
            // 获取消息内容
            String content = new String(message.getBody());
            VerifyEvent event = objectMapper.readValue(content, VerifyEvent.class);
            
            log.info("收到验证事件: {} {}", event.getTicketNumber(), event.isVerified() ? "验证通过" : "验证失败");
            
            // 更新验证状态
            // 此处可以实现相关业务逻辑
            
            // 确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            log.error("处理验证事件失败", e);
            
            // 拒绝消息并重新入队
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
        }
    }
    
    /**
     * 处理服务完成事件
     *
     * @param message 消息
     * @param channel 通道
     */
    @RabbitListener(queues = RabbitMQConfig.QUEUE_STATUS_CHANGE)
    public void handleCompleteServiceEvent(Message message, Channel channel) throws IOException {
        try {
            // 获取消息内容
            String content = new String(message.getBody());
            CompleteServiceEvent event = objectMapper.readValue(content, CompleteServiceEvent.class);
            
            if ("COMPLETE_SERVICE".equals(event.getEventType())) {
                log.info("收到服务完成事件: {} 状态: {}", event.getTicketNumber(), event.getStatus());
                
                // 更新统计数据
                statisticsService.updateServiceStats(
                    event.getServiceTypeId(),
                    event.getWindowId(),
                    event.getServiceTime(),
                    event.getRatingLevel());
                
                // 更新缓存
                String cacheKey = "queue:completed:" + event.getTicketNumber();
                cacheService.set(cacheKey, event.getStatus(), 24, TimeUnit.HOURS);
            }
            
            // 确认消息
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (Exception e) {
            log.error("处理服务完成事件失败", e);
            
            // 拒绝消息并重新入队
            channel.basicNack(message.getMessageProperties().getDeliveryTag(), false, true);
        }
    }
} 